﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using Microsoft.Practices.Unity.InterceptionExtension;
using System.Reflection;

namespace EnCor.CallingTrack
{
    public class ServiceCallHandler : ICallHandler
    {
        public ServiceCallHandler()
        {

        }

        private int _Order = 0;
        #region ICallHandler Members

        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            if (!(input.Target is BizService))
            {
                return getNext().Invoke(input, getNext);
            }

            BizService service = input.Target as BizService;
            MethodBase method = input.MethodBase;
            //ServiceCallInfo info = BuildCallInfo(input);
            ServiceCallInfo callInfo = CallingContext.Current.Push(service, method);

            try
            {
                return getNext().Invoke(input, getNext);
            }
            finally
            {
                if (CallingContext.Current.Peek() != callInfo)
                {
                    throw new CallingTrackException("The calling info is not on the top of calling stack");
                }
                CallingContext.Current.Pop();
            }

        }

        private ServiceCallInfo BuildCallInfo(IMethodInvocation input)
        {
            BizService service = input.Target as BizService;

            return new ServiceCallInfo(service, input.MethodBase);
        }

        public int Order
        {
            get
            {
                return _Order;
            }
            set
            {
                _Order = value;
            }
        }

        #endregion
    }
}
